import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { ComponentPropsType } from '../../components/QuestionComponents';
import { getNextSelectedId, insertNewComponent } from './utils';
import cloneDeep from 'lodash.clonedeep';
import { nanoid } from 'nanoid';
// import { arrayMove } from '@dnd-kit/sortable';
import { arrayMove } from './utils';
export type ComponentInfoType = {
  fe_id: string;
  type: string;
  title: string;
  isHidden: boolean;
  isLocked: boolean;
  props: ComponentPropsType;
};

export type ComponentsStateType = {
  selectedId: string;
  componentList: Array<ComponentInfoType>;
  copiedComponent: ComponentInfoType | null;
  undoStep: number;
};
const initialState: ComponentsStateType = {
  selectedId: '',
  componentList: [],
  copiedComponent: null,
  undoStep: 0,
};

export const componentSlice = createSlice({
  name: 'components',
  initialState,
  reducers: {
    //参数 action： 新的componentList，根据网络数据渲染
    resetComponents: (state: ComponentsStateType, action: PayloadAction<ComponentsStateType>) => {
      state.componentList = action.payload.componentList;
    },
    //参数 action： selectedId
    changeSelectedId: (state: ComponentsStateType, action: PayloadAction<string>) => {
      state.selectedId = action.payload;
    },
    //参数 action： newComponent
    addComponent: (state: ComponentsStateType, action: PayloadAction<ComponentInfoType>) => {
      const newComponent = action.payload;
      insertNewComponent(state, newComponent);
      state.undoStep++;
    },
    //参数 action： newProps
    changeComponentProp: (
      state: ComponentsStateType,
      action: PayloadAction<ComponentPropsType>,
    ) => {
      const newProps = action.payload;
      const { selectedId, componentList } = state;
      const currentComponent = componentList.find((component) => component.fe_id === selectedId);
      if (currentComponent) {
        //如果newProps 有属性为空的时候，赋值默认值
        currentComponent.props = newProps;
        state.undoStep++;
      }
    },
    //删除 component
    deleteComponent: (state: ComponentsStateType) => {
      const { selectedId: removeId, componentList } = state;
      const newSelectedId = getNextSelectedId(removeId, componentList);
      state.selectedId = newSelectedId;
      const index = componentList.findIndex((component) => component.fe_id === removeId);

      if (index !== -1) {
        state.componentList.splice(index, 1);
        state.undoStep++;
      }
    },
    //hidden component: action isHidden
    //必须传fe_id,否则无法显示
    changeComponentHidden: (
      state: ComponentsStateType,
      action: PayloadAction<{ fe_id: string; isHidden: boolean }>,
    ) => {
      const { selectedId, componentList } = state;
      let newSelectedId = '';
      const { fe_id, isHidden } = action.payload;
      //其实可以优化为之处理隐藏情况
      if (isHidden) {
        newSelectedId = getNextSelectedId(selectedId, componentList);
      } else {
        newSelectedId = fe_id;
      }
      state.selectedId = newSelectedId;
      const currentComponent = componentList.find((component) => component.fe_id === fe_id);
      if (currentComponent) {
        currentComponent.isHidden = isHidden;
        state.undoStep++;
      }
    },
    //lock component: 参数 空
    toggleComponentLocked: (state: ComponentsStateType) => {
      const { selectedId, componentList } = state;
      const currentComponent = componentList.find((component) => component.fe_id === selectedId);
      if (currentComponent) {
        currentComponent.isLocked = !currentComponent.isLocked;
        state.undoStep++;
      }
    },
    //copy component: 参数 空
    copySelectedComponent: (state: ComponentsStateType) => {
      const { selectedId, componentList } = state;
      const currentComponent = componentList.find((component) => component.fe_id === selectedId);
      if (currentComponent) {
        state.copiedComponent = cloneDeep(currentComponent);
        state.undoStep++;
      }
    },

    //paste component: 参数 空
    pasteComponent: (state: ComponentsStateType) => {
      const copiedComponent = state.copiedComponent;
      if (copiedComponent == null) return;
      copiedComponent.fe_id = nanoid();
      insertNewComponent(state, copiedComponent);
      state.undoStep++;
    },
    // select pre component
    selectPreComponent: (state: ComponentsStateType) => {
      const { selectedId, componentList } = state;
      const selectedIndex = componentList.findIndex((component) => component.fe_id === selectedId);
      if (selectedIndex <= 0) return;
      state.selectedId = componentList[selectedIndex - 1].fe_id;
    },
    //select next component
    selectNextComponent: (state: ComponentsStateType) => {
      const { selectedId, componentList } = state;
      const selectedIndex = componentList.findIndex((component) => component.fe_id === selectedId);
      if (selectedIndex < 0) return; //未选中
      if (selectedIndex >= componentList.length - 1) return; //选中最后一个
      state.selectedId = componentList[selectedIndex + 1].fe_id;
    },
    //change title
    changeComponentTitle: (state: ComponentsStateType, action: PayloadAction<string>) => {
      const newTitle = action.payload;
      const { selectedId, componentList } = state;
      const currentComponent = componentList.find((component) => component.fe_id === selectedId);
      if (currentComponent) {
        currentComponent.title = newTitle;
        state.undoStep++;
      }
    },
    moveComponent: (
      state: ComponentsStateType,
      action: PayloadAction<{ oldIndex: number; newIndex: number }>,
    ) => {
      const { oldIndex, newIndex } = action.payload;
      state.componentList = arrayMove(state.componentList, oldIndex, newIndex);
      state.undoStep++;
    },
  },
});

export const {
  resetComponents,
  changeSelectedId,
  addComponent,
  changeComponentProp,
  deleteComponent,
  changeComponentHidden,
  toggleComponentLocked,
  copySelectedComponent,
  pasteComponent,
  selectPreComponent,
  selectNextComponent,
  changeComponentTitle,
  moveComponent,
} = componentSlice.actions;
export default componentSlice.reducer;
